home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / sndhrdw / redbaron.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  5KB  |  224 lines

  1. /*
  2.  
  3.     Red Baron sound notes:
  4.     bit function
  5.     7-4 explosion volume
  6.     3    start led
  7.     2    shot (machine gun sound)
  8.     1    squeal (nosedive sound)
  9.     0    POTSEL (rb_input_select)
  10. */
  11.  
  12. #include <math.h>
  13. #include "driver.h"
  14.  
  15. /* used in drivers/redbaron.c to select joystick pot */
  16. extern int rb_input_select;
  17.  
  18. /* Statics */
  19. static INT16 *vol_lookup = NULL;
  20.  
  21. static INT16 vol_crash[16];
  22.  
  23. static int channel;
  24. static int latch;
  25. static int poly_counter;
  26. static int poly_shift;
  27.  
  28. static int filter_counter;
  29.  
  30. static int crash_amp;
  31. static int shot_amp;
  32. static int shot_amp_counter;
  33.  
  34. static int squeal_amp;
  35. static int squeal_amp_counter;
  36. static int squeal_off_counter;
  37. static int squeal_on_counter;
  38. static int squeal_out;
  39.  
  40. WRITE_HANDLER( redbaron_sounds_w )
  41. {
  42.     /* If sound is off, don't bother playing samples */
  43.     if( data == latch )
  44.         return;
  45.  
  46.     stream_update(channel, 0);
  47.     latch = data;
  48.     rb_input_select = data & 1;
  49. }
  50.  
  51. WRITE_HANDLER( redbaron_pokey_w )
  52. {
  53.     if( latch & 0x20 )
  54.         pokey1_w (offset, data);
  55. }
  56.  
  57. static void redbaron_sound_update(int param, INT16 *buffer, int length)
  58. {
  59.     while( length-- )
  60.     {
  61.         int sum = 0;
  62.  
  63.         /* polynome shifter E5 and F4 (LS164) clocked with 12kHz */
  64.         poly_counter -= 12000;
  65.         while( poly_counter <= 0 )
  66.         {
  67.             poly_counter += Machine->sample_rate;
  68.             if( ((poly_shift & 0x0001) == 0) == ((poly_shift & 0x4000) == 0) )
  69.                 poly_shift = (poly_shift << 1) | 1;
  70.             else
  71.                 poly_shift <<= 1;
  72.         }
  73.  
  74.         /* What is the exact low pass filter frequency? */
  75.         filter_counter -= 330;
  76.         while( filter_counter <= 0 )
  77.         {
  78.             filter_counter += Machine->sample_rate;
  79.             crash_amp = (poly_shift & 1) ? latch >> 4 : 0;
  80.         }
  81.         /* mix crash sound at 35% */
  82.         sum += vol_crash[crash_amp] * 35 / 100;
  83.  
  84.         /* shot not active: charge C32 (0.1u) */
  85.         if( (latch & 0x04) == 0 )
  86.             shot_amp = 32767;
  87.         else
  88.         if( (poly_shift & 0x8000) == 0 )
  89.         {
  90.             if( shot_amp > 0 )
  91.             {
  92.                 /* discharge C32 (0.1u) through R26 (33k) + R27 (15k)
  93.                  * 0.68 * C32 * (R26 + R27) = 3264us
  94.                  */
  95. //                #define C32_DISCHARGE_TIME (int)(32767 / 0.003264);
  96.                 /* I think this is to short. Is C32 really 1u? */
  97.                 #define C32_DISCHARGE_TIME (int)(32767 / 0.03264);
  98.                 shot_amp_counter -= C32_DISCHARGE_TIME;
  99.                 while( shot_amp_counter <= 0 )
  100.                 {
  101.                     shot_amp_counter += Machine->sample_rate;
  102.                     if( --shot_amp == 0 )
  103.                         break;
  104.                 }
  105.                 /* mix shot sound at 35% */
  106.                 sum += vol_lookup[shot_amp] * 35 / 100;
  107.             }
  108.         }
  109.  
  110.  
  111.         if( (latch & 0x02) == 0 )
  112.             squeal_amp = 0;
  113.         else
  114.         {
  115.             if( squeal_amp < 32767 )
  116.             {
  117.                 /* charge C5 (22u) over R3 (68k) and CR1 (1N914)
  118.                  * time = 0.68 * C5 * R3 = 1017280us
  119.                  */
  120.                 #define C5_CHARGE_TIME (int)(32767 / 1.01728);
  121.                 squeal_amp_counter -= C5_CHARGE_TIME;
  122.                 while( squeal_amp_counter <= 0 )
  123.                 {
  124.                     squeal_amp_counter += Machine->sample_rate;
  125.                     if( ++squeal_amp == 32767 )
  126.                         break;
  127.                 }
  128.             }
  129.  
  130.             if( squeal_out )
  131.             {
  132.                 /* NE555 setup as pulse position modulator
  133.                  * C = 0.01u, Ra = 33k, Rb = 47k
  134.                  * frequency = 1.44 / ((33k + 2*47k) * 0.01u) = 1134Hz
  135.                  * modulated by squeal_amp
  136.                  */
  137.                 squeal_off_counter -= (1134 + 1134 * squeal_amp / 32767) / 3;
  138.                 while( squeal_off_counter <= 0 )
  139.                 {
  140.                     squeal_off_counter += Machine->sample_rate;
  141.                     squeal_out = 0;
  142.                 }
  143.             }
  144.             else
  145.             {
  146.                 squeal_on_counter -= 1134;
  147.                 while( squeal_on_counter <= 0 )
  148.                 {
  149.                     squeal_on_counter += Machine->sample_rate;
  150.                     squeal_out = 1;
  151.                 }
  152.             }
  153.         }
  154.  
  155.         /* mix sequal sound at 40% */
  156.         if( squeal_out )
  157.             sum += 32767 * 40 / 100;
  158.  
  159.         *buffer++ = sum;
  160.     }
  161. }
  162.  
  163. int redbaron_sh_start(const struct MachineSound *msound)
  164. {
  165.     int i;
  166.  
  167.     vol_lookup = (INT16 *)malloc(32768 * sizeof(INT16));
  168.     if( !vol_lookup )
  169.         return 1;
  170.  
  171.     for( i = 0; i < 0x8000; i++ )
  172.         vol_lookup[0x7fff-i] = (INT16) (0x7fff/exp(1.0*i/4096));
  173.  
  174.     for( i = 0; i < 16; i++ )
  175.     {
  176.         /* r0 = R18 and R24, r1 = open */
  177.         double r0 = 1.0/(5600 + 680), r1 = 1/6e12;
  178.  
  179.         /* R14 */
  180.         if( i & 1 )
  181.             r1 += 1.0/8200;
  182.         else
  183.             r0 += 1.0/8200;
  184.         /* R15 */
  185.         if( i & 2 )
  186.             r1 += 1.0/3900;
  187.         else
  188.             r0 += 1.0/3900;
  189.         /* R16 */
  190.         if( i & 4 )
  191.             r1 += 1.0/2200;
  192.         else
  193.             r0 += 1.0/2200;
  194.         /* R17 */
  195.         if( i & 8 )
  196.             r1 += 1.0/1000;
  197.         else
  198.             r0 += 1.0/1000;
  199.         r0 = 1.0/r0;
  200.         r1 = 1.0/r1;
  201.         vol_crash[i] = 32767 * r0 / (r0 + r1);
  202.     }
  203.  
  204.     channel = stream_init("Custom", 50, Machine->sample_rate, 0, redbaron_sound_update);
  205.     if( channel == -1 )
  206.         return 1;
  207.  
  208.     return 0;
  209. }
  210.  
  211. void redbaron_sh_stop(void)
  212. {
  213.     if( vol_lookup )
  214.         free(vol_lookup);
  215.     vol_lookup = NULL;
  216. }
  217.  
  218. void redbaron_sh_update(void)
  219. {
  220.     stream_update(channel, 0);
  221. }
  222.  
  223.  
  224.